using System;
using System.Collections.Generic;
using T.FAS.Runtime.Base.Entity;
using T.FAS.Runtime.Base.SPI;

namespace T.FAS.Runtime.Base.Dao
{
    public class PlanServiceCache
    {
        private static readonly object syncObject = new object ();
        private static PlanServiceCache instance;
        private Dictionary<string, IQueryPlanService> planService = null;
        private PlanServiceCache()
        {
            planService = new Dictionary<string, IQueryPlanService>();
            InitIQueryPlanService();
        }

        public static PlanServiceCache GetInstance()
        {
            if (instance == null)
            {
                lock (syncObject)
                {
                    if (instance == null)
                        instance = new PlanServiceCache();
                }
            }

            return instance;
        }

        public IQueryPlanService GetIQueryPlanServices(string id)
        {
            if (planService.ContainsKey(id))
            {
                return planService[id];
            }
            else
            {
                throw new FasException($"FAS-Base-QueryPlan-001", $"not exist id:{id}");
            }
        }

        private void InitIQueryPlanService()
        {
            var dao = new QueryPlanConfigDao();
            var plans = dao.GetQueryPlanConfigs();
            if (plans == null) 
                throw new FasException("FAS-Base-QueryPlan-001", $"get query plan info failed");
            Dictionary<string, IQueryPlanService> planServices = new Dictionary<string, IQueryPlanService>();
            foreach (var item in plans)
            {
                if (!string.IsNullOrEmpty(item.Executor))
                {
                    try
                    {
                        Type o = Type.GetType(item.Executor);
                        IQueryPlanService executor = Activator.CreateInstance(o, true) as IQueryPlanService;
                        planServices[item.Name] = executor;
                    }
                    catch (Exception e)
                    {
                        Base.Common.LogUtil.Log(e.ToString(), "QueryPlan");
                    }
                }
            }
            planService = planServices;
        }
    }
}